package roborally;

import java.awt.IllegalComponentStateException;
import java.util.ArrayList;
import java.util.List;

import be.kuleuven.cs.som.annotate.Basic;
import be.kuleuven.cs.som.annotate.Immutable;
import be.kuleuven.cs.som.annotate.Model;
import be.kuleuven.cs.som.annotate.Raw;
import be.kuleuven.cs.som.annotate.Value;

/**
 * A class of coordinates, that has an x- and y-coordinate and a list with all existing coordinates.
 * 
 * @version  1.36
 * @author   Michiel Ruelens & Dieter Naten
 */
public final class Coordinate {

	private final long x;
	private final long y;
	private static ArrayList<Coordinate> coordinateList = new ArrayList<Coordinate>();
		
	/**
	 * Makes a new coordinate with the given x and y values.
	 * 
	 * @param x
	 * 		  The x value the new coordinate should get
	 * @param y
	 *        The y value the new coordinate should get
	 */
	@Model
	private Coordinate(long x, long y){
		this.x = x;
		this.y = y;
	}

	/**
	 * Get a coordinate object with the specified x and y values.
	 * 
	 * @param 	x
	 * 			The desired x-coordinate for the coordinate.
	 * @param 	y
	 * 			The desired y-coordinate for the coordinate.
	 * @return	The desired coordinate object with specified x and y values.
	 * 			| result == new Coordinate(x,y)
	 */
	/*
	* Deze methode gooit geen exceptions omdat alle waarden hier aanvaard worden.
	* Ze geeft puur een coordinaat object terug onafhankelijk van het specifieke doel.
	* De methode die deze methode aanroept moet checken of voor dat specifiek geval aan voorwaarden zijn voldaan.
	* De validatiemethodes onderaan de klasse werken voor borden met alle afmetingen.
	*/
	public static Coordinate getCoordinate(long x, long y) {
		Coordinate resultCoordinate = null;
		if(!coordinateList.isEmpty()){
			for(Coordinate c:coordinateList){
				if(c.getX()==x && c.getY()==y){
					resultCoordinate = c;
				}
			}
		}
		if(resultCoordinate==null){
			resultCoordinate = new Coordinate(x,y);
			coordinateList.add(resultCoordinate);
		}
		return resultCoordinate;
	}

	/**
	 * This method returns the x-value of a coordinate.
	 */
	@Basic
	@Raw
	@Immutable
	public long getX() {
		return x;
	}

	/**
	 * This method returns the y-value of a coordinate.
	 */
	@Basic
	@Raw
	@Immutable
	public long getY() {
		return y;
	}

	/**
	 * This method serves to see if another coordinate has the same values as the current coordinate.
	 * 
	 * @param	other
	 * 			The other coordinate that is being checked whether it has the same coordinate-values as the current one.
	 * @return 	| result ==
	 * 			| (other!=null && this.getClass()==other.getClass() 
	 * 			| && this.getX()==other.getX() && this.getY()==other.getY())
	 */
	@Override
	public boolean equals(Object other){
		if(other==null){
			return false;
		}
		if(this.getClass() != other.getClass()){
			return false;
		}
		Coordinate otherCoordinate = (Coordinate)	other;
		return this.getX()==otherCoordinate.getX() && this.getY()==otherCoordinate.getY();
	}

	/**
	 * Checks if the given x-coordinate is valid.
	 * 
	 * @param	board
	 * 			The board that the x-coordinate is being validated for.
	 * @param	x
	 * 			The x-coordinate that is being validated.
	 * @return	| result == (x>=0 && x<board.getMaxWidth())
	 */
	public static boolean isValidXCoordinate(Board board, long x){
		return x>=0 && x<board.getMaxWidth();
	}

	/**
	 * Checks if the given y-coordinate is valid.
	 * 
	 * @param	board
	 * 			The board that the y-coordinate is being validated for.
	 * @param	y
	 * 			The y-coordinate that is being validated.
	 * @return	| result == (y>=0 && y<board.getMaxHeight())
	 */
	public static boolean isValidYCoordinate(Board board, long y){
		return y>=0 && y<board.getMaxHeight();
	}

	/**
	 * Returns true if the target position does not contain a wall.
	 * 
	 * @param 	board
	 * 			The board that is being checked for walls.
	 * @param 	x
	 * 			The x-coordinate that is being checked for walls.
	 * @param 	y
	 * 			The y-coordinate that is being checked for walls.
	 * @return	| !board.hasWallAtPosition(x,y)
	 * @throws  IllegalArgumentException
	 * 			| if(!isValidXCoordinate(board, x) || !isValidYCoordinate(board, y))
	 */
	public static boolean isOpenCoordinate(Board board, long x, long y) throws IllegalArgumentException {
		if(!isValidXCoordinate(board, x) || !isValidYCoordinate(board, y)){
			throw new IllegalArgumentException();
		}
		return !board.hasWallAtPosition(x, y);
	}

	/**
	 * Combines the methods: isValidYCoordinate(...), isValidXCoordinate(...) and isOpenCoordinate. 
	 * 
	 * @param 	board
	 * 			The board that is being checked for walls.
	 * @param 	x
	 * 			The x-coordinate that is being checked for walls.
	 * @param 	y
	 * 			The y-coordinate that is being checked for walls.
	 * @effect	| (isValidXCoordinate(board,x) && isValidYCoordinate(board,y) && isOpenCoordinate(board,x,y))
	 */
	public static boolean isValidAndOpenCoordinate(Board board, long x, long y) {
		boolean containsWall = board.hasWallAtPosition(x, y);
		return isValidXCoordinate(board, x) && isValidYCoordinate(board, y) && !containsWall;
	}
	
	/**
	 * This methods serves to get the Manhattan Distance between 2 coordinates.
	 * 
	 * @param   c1
	 *          The first coordinate to calculate manhattan distance from/to.
	 * @param   c2
	 *          The second coordinate to calculate manhattan distance from/to.
	 * @return  | result == Math.abs(c1.getX()-c2.getX())+ Math.abs(c1.getY()-c2.getY())
	 * @throws  IllegalArgumentExeception
	 * 			| if(c1 == null || c2 == null)
	 */
	public static long getManhattanDistance(Coordinate c1, Coordinate c2) throws IllegalArgumentException {
		if(c1 == null || c2 == null){
			throw new IllegalArgumentException();
		}
		else{
			return Math.abs(c1.getX()-c2.getX())+ Math.abs(c1.getY()-c2.getY());
		}
	}
	
	/**
	 * This method returns a list of all 4 coordinates sourrounding the specified coordinate.
	 * 
	 * @param   c
	 * 		    The coordinate around which you want to get all coordinates
	 * @return  List with all coordinates surrounding the given coordinate	  
	 * 			| coordinateList.add(Coordinate.getCoordinate(c.getX()+1,c.getY())  
	 * 			| coordinateList.add(Coordinate.getCoordinate(c.getX()-1,c.getY())  
	 * 			| coordinateList.add(Coordinate.getCoordinate(c.getX(),c.getY()+1)  
	 * 			| coordinateList.add(Coordinate.getCoordinate(c.getX(),c.getY()-1)
	 * 			| result ==
	 * 			| coordinateList
	 * @throws  IllegalArgumentExeception
	 * 			| if(c== null)
	 */
	public static List<Coordinate> getFourCoordinatesAroundCoordinate(Coordinate c) throws IllegalArgumentException{
		List<Coordinate> coordinateList = new ArrayList<Coordinate>();
		if(c == null){
			throw new IllegalArgumentException();
		}
		else{
			Coordinate xPlus = Coordinate.getCoordinate(c.getX()+1,c.getY());
			Coordinate xMinus = Coordinate.getCoordinate(c.getX()-1,c.getY());
			Coordinate yPlus = Coordinate.getCoordinate(c.getX(),c.getY()+1);
			Coordinate yMinus = Coordinate.getCoordinate(c.getX(),c.getY()-1);
			coordinateList.add(xPlus);
			coordinateList.add(xMinus);
			coordinateList.add(yPlus);
			coordinateList.add(yMinus);
		}
		return coordinateList;
	}
	
	/**
	 * This method returns a list of all 4 diagonal coordinates sourrounding the specified coordinate.
	 * 
	 * @param   c
	 * 		    The coordinate around which you want to get all diagonal coordinates
	 * @return  List with all diagonal coordinates surrounding the given coordinate	  
	 * 			| result ==
	 * 			| coordinateList
	 * @throws  IllegalArgumentExeception
	 * 			| if(c == null)
	 */
	public static List<Coordinate> getFourDiagonalCoordinatesAroundCoordinate(Coordinate c) throws IllegalArgumentException{
		List<Coordinate> coordinateList = new ArrayList<Coordinate>();
		if(c == null){
			throw new IllegalArgumentException();
		}
		else{
			Coordinate topRight = Coordinate.getCoordinate(c.getX()+1,c.getY()-1);
			Coordinate topLeft = Coordinate.getCoordinate(c.getX()-1,c.getY()-1);
			Coordinate bottomRight = Coordinate.getCoordinate(c.getX()+1,c.getY()+1);
			Coordinate bottomLeft = Coordinate.getCoordinate(c.getX()-1,c.getY()+1);
			coordinateList.add(topRight);
			coordinateList.add(topLeft);
			coordinateList.add(bottomRight);
			coordinateList.add(bottomLeft);
		}
		return coordinateList;
	}
	
	/**
	 * Returns the surrounding coordinates if they are on the board and there are no walls at those places.
	 * 
	 * @param 	c
	 * 			The coordinate around which you want to return the coordinates
	 * @param 	board
	 * 			The board on which you want to return the coordinates
	 * @return 	A list of all coordinates surrounding the given coordinate if there aren't any walls around
	 * @throws  IllegalArgumentExeception
	 * 			| if(c == null || board == null)
	 */
	public static List<Coordinate> getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(Coordinate c, Board board) throws IllegalArgumentException{
		List<Coordinate> coordinateList = new ArrayList<Coordinate>();
		if(c == null || board == null){
			throw new IllegalArgumentException();
		}
		Coordinate xPlus = Coordinate.getCoordinate(c.getX()+1,c.getY());
		Coordinate xMinus = Coordinate.getCoordinate(c.getX()-1,c.getY());
		Coordinate yPlus = Coordinate.getCoordinate(c.getX(),c.getY()+1);
		Coordinate yMinus = Coordinate.getCoordinate(c.getX(),c.getY()-1);
		//in de volgende if-testen is de volgorde belangrijk, want als de eerste niet slaagt, mag de 2e niet gecheckt worden.
		if(xPlus.getX()<=board.getMaxWidth() && !board.hasWallAtPosition(xPlus.getX(),xPlus.getY())){
			coordinateList.add(xPlus);
		}
		if(xMinus.getX()>=0 &&!board.hasWallAtPosition(xMinus.getX(),xMinus.getY())){
			coordinateList.add(xMinus);
		}
		if(yPlus.getY()<=board.getMaxHeight() && !board.hasWallAtPosition(yPlus.getX(),yPlus.getY())){
			coordinateList.add(yPlus);
		}
		if(yMinus.getY()>=0 && !board.hasWallAtPosition(yMinus.getX(),yMinus.getY())){
			coordinateList.add(yMinus);
		}
		return coordinateList;
	}

	/**
	 * Returns if the given coordinate is valid to be a node
	 * 
	 * @param 	c
	 * 			The coordinate for which you want to check if he's valid to be a node
	 * @return 	|(c.getX()>=0 && c.getX()<= Long.MAX_VALUE  && c.getY()>=0 && c.getY()<= Long.MAX_VALUE)
	 */
	public static boolean isValidNodeCoordinate(Coordinate c) {
		return (c.getX()>=0 && c.getX()<= Long.MAX_VALUE  && c.getY()>=0 && c.getY()<= Long.MAX_VALUE);
	}
	
	/**
	 * Returns the coordinate that is directly in front of the given coordinate, according to the orientation given.
	 * If this coordinate is not valid or contains a wall, the original coordinate is returned.
	 * 
	 * @param 	c
	 * 			The coordinate from which you want the coordinate directly in front
	 * @param 	b
	 * 			The board on which you want the coordinate directly in front the given coordinate
	 * @param 	o
	 * 			The orientation in which you want the coordinate directly in front the given coordinate
	 * @effect	| result = getCoordinateInDirection(DirectionOfSearch.FRONT, c, 
	 * 												getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b), o)
	 * @throws  IllegalArgumentExeception
	 * 			| if(c == null || b==null || !Orientation.isValidOrientation(o))
	 */
	public static Coordinate getCoordinateInFront(Coordinate c, Board b, Orientation o) throws IllegalArgumentException{
		if(c == null || b==null || !Orientation.isValidOrientation(o)){
			throw new IllegalArgumentException();
		}
		List<Coordinate> surroundingCoordinates = getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b);
		Coordinate result = c;
		result = getNeighborCoordinateInDirection(DirectionOfSearch.FRONT, c, surroundingCoordinates, o);
		return result;
	}
	
	/**
	 * Returns the coordinate that is directly behind the given coordinate, according to the orientation given.
	 * If this coordinate is not valid or contains a wall, the original coordinate is returned.
	 * 
	 * @param 	c
	 * 			The coordinate from which you want the coordinate directly behind
	 * @param 	b
	 * 			The board on which you want the coordinate directly behind the given coordinate
	 * @param 	o
	 * 			The orientation in which you want the coordinate directly behind the given coordinate
	 * @effect	| result = getCoordinateInDirection(DirectionOfSearch.BEHIND, c, 
	 * 												getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b), o)
	 * @throws  IllegalArgumentExeception
	 * 			| if(c == null || b==null || !Orientation.isValidOrientation(o))
	 */
	public static Coordinate getCoordinateBehind(Coordinate c, Board b, Orientation o) throws IllegalArgumentException{
		if(c == null || b==null || !Orientation.isValidOrientation(o)){
			throw new IllegalArgumentException();
		}
		List<Coordinate> surroundingCoordinates = getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b);
		Coordinate result = c;
		result = getNeighborCoordinateInDirection(DirectionOfSearch.BEHIND, c, surroundingCoordinates, o);
		return result;
	}
	
	/**
	 * Returns the coordinate that is directly to the left of the given coordinate, according to the orientation given.
	 * If this coordinate is not valid or contains a wall, the original coordinate is returned.
	 *
	 * @param 	c
	 * 			The coordinate from which you want the coordinate directly to the left
	 * @param 	b
	 * 			The board on which you want the coordinate directly to the left of the given coordinate
	 * @param 	o
	 * 			The orientation in which you want the coordinate directly to the left of the given coordinate
	 * @effect	| result = getCoordinateInDirection(DirectionOfSearch.LEFT, c, 
	 * 												getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b), o)
	 * @throws  IllegalArgumentExeception
	 * 			| if(c == null || b==null || !Orientation.isValidOrientation(o))
	 */
	public static Coordinate getCoordinateToLeft(Coordinate c, Board b, Orientation o)throws IllegalArgumentException{
		if(c == null || b==null || !Orientation.isValidOrientation(o)){
			throw new IllegalArgumentException();
		}
		List<Coordinate> surroundingCoordinates = getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b);
		Coordinate result = c;
		result = getNeighborCoordinateInDirection(DirectionOfSearch.LEFT, c, surroundingCoordinates, o);
		return result;
	}
	
	/**
	 * Returns the coordinate that is directly to the right of the given coordinate, according to the orientation given.
	 * If this coordinate is not valid or contains a wall, the original coordinate is returned.
	 * 
	 * @param 	c
	 * 			The coordinate from which you want the coordinate directly to the right
	 * @param 	b
	 * 			The board on which you want the coordinate directly to the right of the given coordinate
	 * @param 	o
	 * 			The orientation in which you want the coordinate directly to the right of the given coordinate
	 * @effect	| result = getCoordinateInDirection(DirectionOfSearch.RIGHT, c, 
	 * 												getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b), o)
	 * @throws  IllegalArgumentExeception
	 * 			| if(c == null || b==null || !Orientation.isValidOrientation(o))
	 */
	public static Coordinate getCoordinateToRight(Coordinate c, Board b, Orientation o)throws IllegalArgumentException{
		if(c == null || b==null || !Orientation.isValidOrientation(o)){
			throw new IllegalArgumentException();
		}
		List<Coordinate> surroundingCoordinates = getFourCoordinatesAroundCoordinateThatAreNotWallsAndOnBoard(c, b);
		Coordinate result = c;
		result = getNeighborCoordinateInDirection(DirectionOfSearch.RIGHT, c, surroundingCoordinates, o);
		return result;
	}
	
	/**
	 * An enumeration of directions in which a neighbor coordinate can be searched for.
	 */
	public enum DirectionOfSearch{
		FRONT, BEHIND, RIGHT, LEFT;
	}
	
	/**
	 * Returns a list of orientations that are needed by the method "getCoordinateInDirection" for that particular direction.
	 * 
	 * @param 	directionOfSearch
	 * 			Variable needed to check the needed orientations
	 * @return 	List of orientations needed by the method "getCoordinateInDirection"
	 */
	public static List<Orientation> getOrientationsForDirectionOfSearch(DirectionOfSearch directionOfSearch){
		List<Orientation> orientationList = new ArrayList<Orientation>();
		if(directionOfSearch==DirectionOfSearch.FRONT){
			orientationList.add(Orientation.TOP);
			orientationList.add(Orientation.BOTTOM);
			orientationList.add(Orientation.RIGHT);
			orientationList.add(Orientation.LEFT);
		}
		if(directionOfSearch==DirectionOfSearch.BEHIND){
			orientationList.add(Orientation.BOTTOM);
			orientationList.add(Orientation.TOP);
			orientationList.add(Orientation.LEFT);
			orientationList.add(Orientation.RIGHT);
		}
		if(directionOfSearch==DirectionOfSearch.LEFT){
			orientationList.add(Orientation.RIGHT);
			orientationList.add(Orientation.LEFT);
			orientationList.add(Orientation.TOP);
			orientationList.add(Orientation.BOTTOM);
		}
		if(directionOfSearch==DirectionOfSearch.RIGHT){
			orientationList.add(Orientation.LEFT);
			orientationList.add(Orientation.RIGHT);
			orientationList.add(Orientation.BOTTOM);
			orientationList.add(Orientation.TOP);
		}
		return orientationList;
	}
	
	/**
	 * Returns a neighbor coordinate of c, in the desired direction(for example DirectionOfSearch.LEFT), 
	 * given an orientation(for example Orientation.RIGHT). (in the example the result would be the coordinate to
	 * the top of the given c (lower y-coordinate) because the given orientation is Orientation.RIGHT, 
	 * and to the left of Orientation.RIGHT is Orientation.TOP).
	 * If that resulting coordinate contains a wall or does not exist on the board, the original coordinate is returned.
	 * 
	 * @param 	directionOfSearch
	 * 			The direction of searching
	 * @param 	c
	 * 			The coordinate from which you want to search
	 * @param 	surroundingCoordinates
	 * 			List of surrounding coordinates of the given coordinate
	 * @param 	o
	 * 			The orientation needed for searching
	 * @return  The coordinate you needed following the description of this method
	 * @throws  IllegalArgumentExeception
	 * 			| if(c == null || !Orientation.isValidOrientation(o))
	 */
	public static Coordinate getNeighborCoordinateInDirection(DirectionOfSearch directionOfSearch, Coordinate c, List<Coordinate> surroundingCoordinates, Orientation o)throws IllegalArgumentException{
		if(c == null || !Orientation.isValidOrientation(o)){
			throw new IllegalArgumentException();
		}
		List<Orientation> orientationList = getOrientationsForDirectionOfSearch(directionOfSearch);
		Coordinate result = c;
		if(o == orientationList.get(0) && surroundingCoordinates.contains(getCoordinate(c.getX(),c.getY()-1))){
			result =  getCoordinate(c.getX(),c.getY()-1);
		}
		if(o == orientationList.get(1) && surroundingCoordinates.contains(getCoordinate(c.getX(),c.getY()+1))){
			result =  getCoordinate(c.getX(),c.getY()+1);
		}
		if(o == orientationList.get(2) && surroundingCoordinates.contains(getCoordinate(c.getX()+1,c.getY()))){
			result =  getCoordinate(c.getX()+1,c.getY());
		}
		if(o == orientationList.get(3) && surroundingCoordinates.contains(getCoordinate(c.getX()-1,c.getY()))){
			result =  getCoordinate(c.getX()-1,c.getY());
		}
		return result;
	}
	
	public static Coordinate getCoordinateInDirectionThatContainsPlaceable(Orientation orientation, Board board, Robot robot){
		Coordinate resultCoordinate = null;
		boolean searching = true;
		if(orientation == Orientation.TOP){
			for(long i = robot.getCoordinate().getY()-1;i>=0 && searching == true;i--){
				if(board.hasPlaceableAtPosition(robot.getCoordinate().getX(),i)){
					resultCoordinate = Coordinate.getCoordinate(robot.getCoordinate().getX(),i);
					searching = false;
				}
			}
		}
		else if(orientation == Orientation.RIGHT){
			for(long i = robot.getCoordinate().getX()+1;i<=board.getWidth() && searching == true;i++){
				if(board.hasPlaceableAtPosition(i,robot.getCoordinate().getY())){
					resultCoordinate = Coordinate.getCoordinate(i,robot.getCoordinate().getY());
					searching = false;
				}
			}
		}
		else if(orientation == Orientation.BOTTOM){
			for(long i = robot.getCoordinate().getY()+1;i<=board.getHeight() && searching == true;i++){
				if(board.hasPlaceableAtPosition(robot.getCoordinate().getX(), i)){
					resultCoordinate = Coordinate.getCoordinate(robot.getCoordinate().getX(),i);
					searching = false;
				}
			}
		}
		else if(orientation == Orientation.LEFT){
			for(long i = robot.getCoordinate().getX()-1;i>=0 && searching == true;i--){
				if(board.hasPlaceableAtPosition(i,robot.getCoordinate().getY())){
					resultCoordinate = Coordinate.getCoordinate(i,robot.getCoordinate().getY());
					searching = false;
				}
			}
		}
		return resultCoordinate;
	}
	
	
	/** 
	 * Checks whether 2 placeables are standing next to each other.
	 * 
	 * @param 	coordinate1
	 * 			One of 2 placeables that is being checked.
	 * @param 	coordinate2
	 * 			The other placeable that is being checked.
	 * @throws	IllegalComponentStateException()
	 * 			When one of the placeables is terminated.
	 * 			| if(placeable1.isTerminated() || placeable2.isTerminated())
	 * @return 	Returns true if the 2 placeables are indeed standing next to each other, otherwise returns false.
	 *			| result==
	 *			| (placeable1.getX()==placeable2.getX() && Math.abs(placeable2.getY()-placeable1.getY())==1) ||
	 *			| (Math.abs(placeable2.getX()-placeable1.getX())==1 && placeable1.getY()==placeable2.getY())
	 */
	public static boolean standNextToEachOther(Coordinate coordinate1, Coordinate coordinate2){
		boolean result = false;
		long x1 = coordinate1.getX();
		long x2 = coordinate2.getX();
		long y1 = coordinate1.getY();
		long y2 = coordinate2.getY();
		if(x1==x2 && Math.abs(y2-y1)==1){
			result = true;
		}
		else if(Math.abs(x2-x1)==1 && y1==y2){
			result = true;
		}
		return result;
	}
	
	public static boolean standDiagonalNextToEachOther(Coordinate coordinate1, Coordinate coordinate2) {
		boolean result = false;
		long x1 = coordinate1.getX();
		long x2 = coordinate2.getX();
		long y1 = coordinate1.getY();
		long y2 = coordinate2.getY();
		if(Math.abs(x2-x1)==1 && Math.abs(y2-y1)==1){
			result = true;
		}
		return result;
	}
	
	/**
	 * This method returns a list containing all adjacent coordinates. This includes the coordinate itself, the coordinates
	 * to the right,left,bottom and top of the coordinate, and the diagonal coordinates topRight,topLeft,bottomRight and bottomLeft of the coordinate.
	 * @param 	c
	 * 			The coordinate for which adjacent coordinates are wanted.
	 * @return	A list containing all adjacent coordinates.
	 */
	public static List<Coordinate> getAllAdjacentCoordinates(Coordinate c){
		List<Coordinate> coordinateList = new ArrayList<Coordinate>();
		coordinateList.addAll(getFourCoordinatesAroundCoordinate(c));
		coordinateList.addAll(getFourDiagonalCoordinatesAroundCoordinate(c));
		coordinateList.add(c);
		return coordinateList;
	}
}